package com.lanhao.aot.ip2region;

import java.sql.SQLException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Lists;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;

public class Ip2Region {

	public static Map<Integer, List<Entity>> ip2RegionMap = new LinkedHashMap<>(); // 全部数据集合
	public static Map<String, Integer> ip2RegionIndexMap = new LinkedHashMap<>(); // 索引Map

	public static final Integer everySectionLineNum = 5000; // 每一段的数据行数

	static {
//		long start = System.currentTimeMillis();
		try {
			List<Entity> allList = Db.use().findAll("t_ip_address");
			// 查出来后按starNum升序处理
			Collections.sort(allList, new Comparator<Entity>() {
				public int compare(Entity o1, Entity o2) {
					Long startNum1 = o1.getLong("start_num");
					Long startNum2 = o2.getLong("start_num");
					if (startNum1 > startNum2) {
						return 1;
					}
					if (startNum1 < startNum2) {
						return -1;
					}
					return 0;
				}
			});
//			System.out.println("全部数据的长度size==" + allList.size());
			List<List<Entity>> subIpList = Lists.partition(allList, everySectionLineNum);
			for (int i = 0; i < subIpList.size(); i++) {
				List<Entity> subSectionList = subIpList.get(i);
				ip2RegionMap.put(i, subSectionList);
				Long startNum1 = subSectionList.get(0).getLong("start_num");
				Long startNum2 = subSectionList.get(subSectionList.size() - 1).getLong("start_num");
				ip2RegionIndexMap.put(startNum1 + "_" + startNum2, i);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
//		long end = System.currentTimeMillis();

//		System.out.println("数据加载完毕,耗时cost=" + (end - start) + "ms");
	}

	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			new Runnable() {
				@Override
				public void run() {
					long start = System.currentTimeMillis();
					String areaId = getAreaId(604327675L);
//					System.out.println("查找到的areaId=" + areaId);
					long end = System.currentTimeMillis();
					System.out.println("查找耗时=" + (end - start) + "ms");
				}
			}.run();
		}
	}

	private static String getAreaId(Long ipNum) {
		Integer index = getListIndex(ipNum);
		if (index == null) {
			return StringUtils.EMPTY;
		}
		List<Entity> ip2RegionList = ip2RegionMap.get(index);
		List<Entity> avaliableList = ip2RegionList.stream()
				.filter(s -> ipNum >= s.getLong("start_num") && ipNum <= s.getLong("end_num"))
				.collect(Collectors.toList());
		if(avaliableList.size() > 1) {
			// 按sort大小升序,此处较耗时
			Collections.sort(avaliableList, new Comparator<Entity>() {
				public int compare(Entity o1, Entity o2) {
					Integer startNum1 = o1.getInt("sort");
					Integer startNum2 = o2.getInt("sort");
					if (startNum1 > startNum2) {
						return 1;
					}
					if (startNum1 < startNum2) {
						return -1;
					}
					return 0;
				}
			});
		}

		return avaliableList.get(0).getStr("areaid");
	}

	private static Integer getListIndex(Long ipNum) {
		Set<Entry<String, Integer>> entrySet = ip2RegionIndexMap.entrySet();
		Iterator<Entry<String, Integer>> iterator = entrySet.iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, Integer> entry = iterator.next();
			String key = entry.getKey();
			int value = entry.getValue();
			String[] split = key.split("_");
			Long startNum1 = Long.valueOf(split[0]);
			Long startNum2 = Long.valueOf(split[1]);
			if (ipNum >= startNum1 && ipNum <= startNum2) {
				return value;
			}
		}
		return null;
	}
}
